home *** CD-ROM | disk | FTP | other *** search
- ;---------------
- ; BIOS module for the D86 debugger
- ;---------------
-
- ; Copyright (C)1987 Eric Isaacson. All rights reserved. Permission to
- ; copy and use this module is granted ONLY for machines registered for both
- ; the A86 assembler and the D86 debugger.
-
- ; Current support: IBM-PC, Wang PC, TI-PC, Sanyo 555, and Tandy 2000
-
- ; This module defines the BIOS interface for my D86 debugger. I am publishing
- ; it to assist those who wish to assist me in implementing D86 on machines not
- ; BIOS-compatible with the IBM-PC. To support a non-standard BIOS, we must
- ; provide new keyboard codes, new action routines, and several other data
- ; quantities. The scenario for this is as follows:
-
- ; First, the debugger calls the procedure SET_MACHINE. This procedure must
- ; detect what kind of machine it is running on, and set two variables:
- ;
- ; * SUBDIR_CHAR, a byte giving the character that indicates a subdirectory for
- ; an MS-DOS path name on your computer. On an IBM-PC this is a backslash \
- ; (e.g. a file name can be \usr\eric\foo.com); on a Wang this is an ordinary
- ; backslash (e.g. the same file is /usr/eric/foo.com).
- ;
- ; * BIOS_INIT, a pointer to a procedure that does BIOS-specific
- ; initializations.
- ;
- ; Next, after performing some internal initializations, the debugger calls the
- ; BIOS_INIT routine. That routine must do three things:
- ;
- ; 1. The routine must point SI to a special data structure (which I'll
- ; describe shortly), then call the routine NEW_KEYS, to propagate the
- ; items in the structure to the necessary places throughout the debugger.
- ;
- ; 2. The routine must perform any initializations necessary for this BIOS.
- ; For example, WANG_CONFIG locates and stores the port number for hardware
- ; that enables video access on the Wang.
- ;
- ; 3. The routine must decide if the debugger is running on the same screen as
- ; the user program. If it is, it must move the user's cursor to the lower
- ; left corner of the screen.
- ;
- ; The structure fed to NEW_KEYS contains all the data necessary for ongoing
- ; debugger execution under the new BIOS. See the structure WANG_KEYS for a
- ; prototype. The structure consists of the following:
- ;
- ; * a byte giving the keyboard code for the debugger's HELP key.
- ;
- ; * a byte declaring the difference between your BIOS's key codes for
- ; function keys, and the IBM BIOS's key codes. Your BIOS_KEY must return
- ; consecutive values for the function keys F1 through F10. You should
- ; declare this byte to be X - FUNC, where X is one less than the code
- ; returned by the F1 key. For example, since the Wang F1 key returns hex
- ; 080, the byte is declared 07F - FUNC.
-
- ; * a number of bytes giving code values for all the other control keys
- ; used by the debugger. This list will be expanding with new versions;
- ; see WANG_KEYS for the current version's list. You should precede the list
- ; with the L1 label, and follow it with the declaration N_CONTROL_KEYS EQU
- ; $-L1, exactly as shown. Don't change the name N_CONTROL_KEYS; the
- ; redeclaration of the same name insures that you've gotten the right number
- ; of codes into the table.
- ;
- ; * a word pointing to a message string with the name of the help-key. If your
- ; keyboard has a key labelled HELP, use the name HELP_HELP as in WANG_KEYS.
- ; If there is another key nonexistent on the IBM-PC (e.g. F11), then put
- ; a new name (e.g. F11_HELP) following DW; I'll supply the definition for
- ; the new name. If there is no extra key and no HELP key, use Alt-F10 as
- ; on the IBM-PC, and declare DW ALTF10_HELP here.
- ;
- ; * the label L2: to be used to verify the number of following bytes.
- ;
- ; * pointers to your BIOS's versions of the procedures VID_COPY, VID_ATTR,
- ; VID_FIX, BIOS_BELL, and BIOS_KEY, described shortly. Substitute the name
- ; of your machine for VID and BIOS in the generic names; e.g. the WANG_KEYS
- ; structure has WANG_COPY, WANG_ATTR, WANG_BELL, and WANG_KEY.
- ;
- ; * a word giving the segment register value for video memory on your machine.
- ; The debugger will supply this value in the ES register when it calls
- ; VID_COPY and VID_ATTR. That is all the debugger does with it; so this
- ; value can really be anything that the BIOS's versions of VID_COPY and
- ; VID_ATTR want.
- ;
- ; * a byte giving the attribute value for normal video. This attribute will
- ; be in effect for the entire debugger screen, except for the location of
- ; the debugger's cursor.
- ;
- ; * a byte giving the attribute value for reverse video. This attribute will
- ; be used to mark the debugger cursor.
- ;
- ; * the declaration N_BIOS_CALLS EQU ($-L2)/2 Again, don't change the name;
- ; the redeclaration of the name insures you didn't leave anything out.
- ;
- ; This completes the description of the structure fed to NEW_KEYS. After
- ; BIOS_INIT is called, the debugger will keep calling 7 action routines to
- ; perform its interactive I/O. The routines must perform actions as
- ; follows:
-
- ; VID_COPY copies CL bytes of characters from DS:SI to the video memory whose
- ; location is given by ES:DI. The characters should have the attribute
- ; NORM_ATTR, which the caller will place into AH for VID_COPY's convenience.
- ; VID_COPY must place the character byte and the attribute byte into each
- ; output video word. VID_COPY must return with BL preserved, the high byte
- ; of SI preserved (it will be if you leave SI pointing beyond the bytes
- ; copied), and DI advanced beyond the video memory just output. The caller
- ; assumes that video memory can be found at the value of VIDEO_SEG set by
- ; BIOS_INIT, starting at offset 0, and proceeding consecutively, one 16-bit
- ; memory word for every character. The caller will set CH=0 for its first
- ; call, so that VID_COPY can use CX as the count; but if it does, it must
- ; return CH=0 for subsequent calls.
-
- ; VID_ATTR places the attribute byte AL into the video word whose location is
- ; given by ES:DI. The character byte of the video word must not be disturbed.
-
- ; VID_FIX restores a video screen that might have been clobbered by programs
- ; external to the debugger. If VID_COPY copies all characters to video memory
- ; every time, then VID_FIX should RET without doing anything. If, however,
- ; VID_COPY tries to keep track of which characters are already on the screen,
- ; and suppress video output for those that are, then VID_FIX should disable
- ; the suppression feature, call the debugger's routine REFRESH to update the
- ; whole screen, then re-enable the suppression feature.
-
- ; BIOS_BELL rings the bell. NOTE that it is not acceptible for BIOS_BELL to
- ; use the MS-DOS write routine to send a bell control-code to standard output;
- ; if it did, then the debugger couldn't debug programs that have redirected
- ; their standard output-- the bell code would go to the user program's output
- ; file, and not be translated into a beep.
-
- ; BIOS_KEY returns in AL a code for a single keystroke. The code should be
- ; compatible with the values placed into the debugger's function tables by
- ; BIOS_INIT. If there is no keystroke available, BIOS_KEY should wait until
- ; there is one. BIOS_KEY should return on each individual key, and not wait
- ; for any line-editing to take place.
-
- ; BIOS_SAVE saves whatever there is about the user program's BIOS state that
- ; might be clobbered by the debugger. Currently, the only such thing is
- ; the user's cursor position on the Sanyo. So on all machines but the Sanyo,
- ; this is a "do-nothing" routine.
-
- ; BIOS_RESTORE restores the BIOS state saved by BIOS_SAVE. Again, this routine
- ; does nothing except on the Sanyo, on which it restores the user cursor
- ; position, clobbered because D86 must use BIOS calls to write to the Sanyo
- ; screen.
-
- ; SET_MACHINE determines what kind of machine we are running on, and sets
- ; the variables SUBDIR_CHAR and BIOS_INIT accordingly.
-
- TI_MSG_PTR DD 0F400:0A022
-
- TI_MSG:
- DB 'Texas I'
- TI_MSG_LEN EQU $-TI_MSG
-
- TANDY_MSG1_PTR DD 0FC00:0002F ; There are two BIOS versions for
- TANDY_MSG2_PTR EQU 0032 ; the Tandy 2000 slightly different
-
- TANDY_MSG:
- DB 'Tandy'
- TANDY_MSG_LEN EQU $-TANDY_MSG
-
- L2: ; BH is not 1
- ADD BH,2 ; was BH 0FF?
- JNZ RET ; return if not -- we are on an IBM-PC
- MOV ES,AX,0FFFF ; it was-- address the end of ROM
- ES CMP AX,[6] ; are there FFFF's beyond the boot-JMP?
- MOV AX,SANYO_CONFIG ; load Sanyo address, in case there were
- JE >L1 ; jump if there were-- it is a Sanyo
- RET
-
- SET_MACHINE:
- CMP DH,DH ; set Z so a JMP can be patched into NOPS
- NOP ; you could patch a JMP to force a specific interface
- NOP
- LES DI,TI_MSG_PTR ; point to the identifying message in the TI-PC ROM
- MOV SI,TI_MSG ; point to our copy of that message
- MOV CX,TI_MSG_LEN ; load the number of bytes that we have
- REPE CMPSB ; is the message there in ROM?
- MOV AX,TIPC_CONFIG ; load pointer to TI-PC's BIOS_INIT in case it is
- JE >L1 ; jump if it is, to store the pointer
- LES DI,TANDY_MSG1_PTR ; point to the identifying message in the T2K ROM
- MOV SI,TANDY_MSG ; point to Tandy identifying message
- MOV CX,TANDY_MSG_LEN ; length of message to compare
- PUSH SI,CX ; save pointer+count in case we have to try other place
- REPE CMPSB ; check for match in ROM header
- POP CX,SI ; restore count and pointer
- MOV AX,TANDY_CONFIG ; set pointer to Tandy 2000 BIOS_INIT
- JE >L1 ; jump and store pointer if we found it
- MOV DI,TANDY_MSG2_PTR ; point to second version message in the T2K ROM
- REPE CMPSB ; check for match in ROM header
- JE >L1 ; jump and store pointer if we found it
- MOV AH,030 ; MS-DOS function number for VERSION
- INT 33 ; fetch the version; we want the machine code BH
- DEC BH ; if BH was 1 we are on a Wang PC
- JNZ L2 ; variables already set if we are on an IBM-PC
- MOV SUBDIR_CHAR,'/' ; subdirectory character on a Wang is /
- MOV AX,WANG_CONFIG ; action routine for TI-PC is TIPC_CONFIG
- L1:
- MOV BIOS_INIT,AX ; store the action routine for this machine
- RET
-
-
- ; IBM_CONFIG is the BIOS_INIT routine for the IBM-PC. Since its NEW_KEY
- ; values are the defaults, we do not need to call NEW_KEY.
-
- IBM_CONFIG:
- MOV AH,15 ; function number for GET_VIDEO_MODE
- INT 16 ; call the BIOS to get the mode
- CMP AL,7 ; are we in monochrome mode?
- MOV AX,0B000 ; load monochrome map location in case yes
- IF B MOV AH,0B8 ; if not then load color map location
- MOV BL,V_FLAG ; load the setting of the -V switch
- XOR AH,BL ; switch intefaces if we saw a -V in invocation
- CS MOV VIDEO_SEG,AX ; store the location of physical video
- TEST AH,8 ; are we on a CGA video board?
- JZ >L1 ; skip if not
- CS MOV VID_COPY,COLOR_COPY ; we are: change the video-copy routine
- CS MOV BIOS_RESTORE,COLOR_RESTORE
- CS MOV REV_ATTR,0F0 ; change the reverse-video to blinking
- L1:
- TEST BL ; are we the same screen as the user program?
- JNZ RET ; return if we are not-- no need to move cursor
- SET_IBM_LOW_LEFT:
- MOV BH,0 ; page number is zero
- MOV DX,24 BY 0 ; we will move the cursor to row 24, column 0
- SET_IBM_CURSOR:
- MOV AH,2 ; video BIOS function number for SET CURSOR POSITION
- INT 16 ; call the BIOS to put user cursor in lower left corner
- RET
-
-
- ; IBM_FIX performs a fixup of a trashed screen on an IBM machine.
-
- ; COLOR_RESTORE checks to see if the debugger screen has been trashed. If it
- ; has, we restore the screen.
-
- COLOR_RESTORE:
- PUSH DS
- MOV DS,AX,0B800
- MOV DX,03DA ; load the port number for reading the video status
- L2: ; loop here to wait for vertical retrace
- IN AL,DX ; input the status
- TEST AL,1 ; mask the retrace bit
- JZ L2 ; loop if we are not in vertical retrace
- CMP B[2400],'A'
- POP DS
- JE RET
- IBM_FIX:
- CS PUSH VID_COPY ; save the old VID_COPY value
- CS MOV VID_COPY,MONO_COPY ; coerce it to MONO_COPY, to blindly copy all
- CALL REFRESH ; refresh the screen; let the snow scatter!
- CS POP VID_COPY ; restore the old VID_COPY value
- IBM_SAVE:
- IBM_RESTORE:
- RET
-
-
- ; MONO_COPY is the VID_COPY routine for an IBM monochrome video board. The
- ; characters occupy the lower byte of the DI-pointed words. We can afford
- ; to rewrite the entire screen on each refresh; so no special action needs to
- ; be taken. We do complicated looping to make the routine as fast as
- ; possible.
-
- MONO_COPY:
- SHR CX,1 ; is the character count odd?
- JC >L5 ; jump if yes, to special code
- L1:
- SHR CX,1 ; is the character count a multiple of 4?
- JC >L6 ; jump if not, to special code
- L2: ; loop here to copy every 4 bytes
- LODSB ; load the character from the source
- STOSW ; output the character, with the standard attribute byte
- LODSB ; char # 2
- STOSW
- LODSB ; char # 3
- STOSW
- LODSB ; char # 4
- STOSW
- LOOP L2 ; loop for the next 4 characters
- RET
-
- L5: ; the character count was odd
- MOVSB ; copy the odd character to the video buffer
- INC DI ; advance beyond the attribute byte
- JCXZ RET ; return if count is depleted
- JMP L1 ; join even code
-
- L6: ; the character count is 2 mod 4
- LODSB ; load one character
- STOSW ; output it and the attribute-- count now 1 mod 4
- LODSB ; load second character
- STOSW ; output it-- count now 0 mod 4
- JCXZ RET ; return if count is depleted
- JMP L2 ; join multiple-of-4 code
-
-
- ; COLOR_COPY is the VID_COPY routine for an IBM Color Graphics Adapter board.
- ; The characters occupy the lower byte of the DI-pointed words. We must wait
- ; for vertical retrace to output our data, to avoid annying "snow" on the
- ; screen. So we can't afford to output the entire buffer every time. So we
- ; maintain at [SI+81] a copy of what's already on the screen for [SI], and we
- ; output only if the buffer is new.
-
- COLOR_COPY:
- PUSH BX ; preserve BX across the call
- MOV DX,03DA ; load the port number for reading the video status
- SKIP2 ; skip to the LODSB instruction
- L0: ; loop here for every character that is already out there
- INC DI ; advance the output pointer beyond the character
- L1: ; loop here after a non-matching character was stored
- INC DI ; advance beyond the following attribute byte
- LODSB ; fetch the next character
- MOV BL,AL ; save the character in BL
- XCHG AL,[SI+79] ; swap it with the already-out-there value
- CMP AL,BL ; is the character already out there?
- LOOPE L0 ; loop if it is
- JE >L4 ; jump if the characters are exhausted
- L2: ; loop here to wait for vertical retrace
- IN AL,DX ; input the status
- TEST AL,1 ; mask the retrace bit
- JZ L2 ; loop if we are not in vertical retrace
- MOV AL,BL ; re-fetch the character to be output
- STOSB ; output the character
- INC CX ; undo the previous LOOPE's decrement of CX
- LOOP L1 ; loop to check for another output character
- INC DI ; advance beyond the attribute byte of the last character
- POP BX ; restore clobbered register
- RET
-
- L4: ; matching character was the last in the buffer
- INC DI,2 ; advance beyond the output video word
- POP BX ; restore clobbered register
- RET
-
-
- ; IBM_ATTR is the VID_ATTR routine for IBM-PC compatible computers. The
- ; attribute byte is the high byte of the DI-pointed video word.
-
- IBM_ATTR:
- INC DI ; advance to the high, attribute byte
- STOSB ; output the attribute code AL to the byte
- RET
-
-
- ; IBM_KEY is the BIOS_KEY routine for IBM_PC compatible computers. We must
- ; transform the two-byte code returned by the IBM BIOS into the single
- ; code AL expected by the rest of the debugger.
-
- IBM_KEY:
- MOV AH,0 ; function code for GET KEY
- INT 016 ; get the keystroke from the IBM BIOS
- TEST AL ; is the return AL nonzero?
- JNZ RET ; if yes then AL is our return code
- MOV AL,AH ; AL is zero, so AH determines the return code
- ADD AL,080-16 ; shift the values into a range not seen directly in AL
- RET
-
-
- ; IBM_BELL is the BIOS_BELL routine for IBM-PC compatible computers. We
- ; output the code 07 to the BIOS's console output routine.
-
- IBM_BELL:
- MOV AX,0E07 ; AH= console out function number; AL="BELL" control code
- INT 010 ; output BELL to the console
- RET
-
-
- ; NEW_KEYS reassigns the keyboard codes and the action routines for a non-
- ; IBM-compatible BIOS. We are called with CS:SI pointing to a table of
- ; various new values, whose format is identical to the one given by
- ; WANG_KEYS below. The new values are plugged into the various tables
- ; in the debugger, so that correct actions are taken for the non-compatible
- ; machine.
-
- NEW_KEYS:
- PUSH DS ; preserve DS across call
- MOV DS,CS ; point DS to our program, to read the table at SI
- MOV ES,CS ; also point the destination segment to our program
- LODSB ; load the first byte of the table
- MOV HELP_KEY,AL ; first byte is the code for HELP_KEY
- LODSB ; load the second byte
- ADD SWITCH_KEY,AL ; byte 2 is (new-IBM) function-key-codes-difference
- MOV DI,CTRL_JUMPS+2 ; point to the control-jumps table
- MOV CX,N_FUNCS ; load the number of function-keys in that table
- L1: ; loop here to adjust each function-key code
- ADD [DI],AL ; add the code into the table entry
- ADD DI,3 ; advance to the next table entry
- LOOP L1 ; loop to adjust the next table entry
- MOV CL,N_CONTROL_KEYS ; load the number of subsequent keys in the table
- L2: ; loop here to plug in the new value for each key
- MOVSB ; copy the new key code to the function table
- INC DI,2 ; advance output pointer to the next key code
- LOOP L2 ; loop to plug in the next key code
- LODSW ; fetch the message-pointer to the name of HELP key
- MOV HELP_MSG,AX ; plug the pointer into the messages-string
- MOV DI,BIOS_CALLS ; point to the table of action routines
- MOV CX,N_BIOS_CALLS ; load the count of words in action-routine-table
- REP MOVSW ; copy the new pointers to the table
- POP DS ; restore clobbered register
- RET
-
-
-
- ;------------------
- ; WANG INTERFACE
- ;------------------
-
- ; Thanks to Alan Tschetter for providing the information necessary for me
- ; to program this interface.
-
- WANG_KEYS:
- DB 0E1 ; HELP key value
- DB 07F-FUNC ; add-quantity for FUNC
- L1:
- DB 0C2,0C9,0C0,0C8,0C4 ; DOWN, NEXT, UP, PREV, HOME
- DB 097,097 ; shift-F7 key, disabled Alt-F9 key
- N_CONTROL_KEYS EQU $-L1
-
- DW HELP_HELP ; pointer to "HELP" message, the name of Wang's HELP key
-
- L2:
- DW WANG_COPY ; VID_COPY routine
- DW WANG_ATTR ; VID_ATTR routine
- DW RET ; there is no VID_FIX necessary on the Wang
- DW WANG_BELL ; BIOS_BELL routine
- DW WANG_KEY ; BIOS_KEY routine
- DW RET
- DW RET
- DW 0F000 ; new value for VIDEO_SEG
- DB 0 ; normal-video attribute for the Wang PC
- DB 2 ; reverse-video attribute for the Wang PC
- N_BIOS_CALLS EQU ($-L2)/2
-
-
- ; Other Wang keycodes: F1--F16 80--8F
- ; Prev C8 Erase CB
- ; Insert C6 Delete C7
- ; <--- C3 ---> C1
- ; EXEC C5
- ; All the above codes add 010 for SHIFT versions.
- ; NO ALT KEY!!!
- ; Print E3 Back Tab CD
- ; Cancel E0 Shift Cancel 03
-
-
- ; WANG_CONFIG is the BIOS initialization routine for a Wang PC. We copy the
- ; values of WANG_KEYS to various locations, then we fetch the value of
- ; ENABLE_PORT, that lets us access Wang's video memory, then we move the
- ; user's cursor to the lower left corner.
-
- L1: ; console codes to move cursor to lower left corner
- DB 01B,'[25;1H' ; row 25, column 1
- L2 EQU $-L1 ; L2 is the count of bytes
-
- WANG_CONFIG:
- MOV SI,WANG_KEYS ; point to Wang's table of key codes and other values
- CALL NEW_KEYS ; plug the new values into our program's data structures
- MOV AL,1 ; function code for GET BIOS ENVIRONMENT
- INT 088 ; sets ES to a segment where we'll find port #
- ES MOV BX,[BX+10] ; fetch a pointer
- ES MOV AH,[BX+19] ; use the pointer to fetch the high of the port #
- MOV AL,010 ; low of the port # is always 010
- MOV ENABLE_PORT,AX ; store the port number
- MOV DS,CS ; point DS to our program, for console sequence
- MOV DX,L1 ; point DX to the "go to lower left" console sequence
- MOV CX,L2 ; load the number of bytes in the sequence
- MOV BH,0 ; device number, maybe? I don't know for sure
- MOV AL,0D ; function number, maybe? I don't know for sure
- INT 088 ; output escape string, user's cursor goes to lower left
- RET
-
-
- ; WANG_COPY is the Wang-PC version of the VID_COPY routine. The character
- ; and attribute bytes are reversed from what they are on the IBM-PC, so
- ; AH and AL are swapped before and after every word output. There are no
- ; snow problems; so we can get away with copying everything every time.
- ; We do need to enable the video memory, though.
-
- WANG_COPY:
- MOV DX,ENABLE_PORT ; fetch the port number for enabling video memory
- MOV AL,1 ; value 1 causes memory to be enabled
- OUT DX,AL ; we can now access the video memory
- L1: ; loop here for each character to be copied
- LODSB ; fetch the next character
- XCHG AH,AL ; swap character into AH, attribute byte into AL
- STOSW ; output the word to video memory
- MOV AH,AL ; copy the attribute byte back to AH, for next char
- LOOP L1 ; loop to copy the next character
- L2: ; common exit with WANG_ATTR
- MOV AL,0 ; value 0 shuts off access to video memory
- OUT DX,AL ; video access is now disabled
- RET
-
-
- ; WANG_ATTR is the Wang-PC version of the VID_ATTR routine. The attribute
- ; byte is the low byte of the DI-pointed video memory. Also, to access it,
- ; we must send the code that enables Wang video memory.
-
- WANG_ATTR:
- PUSH AX ; preserve the attribute code
- MOV DX,ENABLE_PORT ; fetch the port number for enabling video memory
- MOV AL,1 ; value 1 causes memory to be enabled
- OUT DX,AL ; we can now access the video memory
- POP AX ; restore the attribute code
- STOSB ; output the attribute byte to the LOW byte of video word
- JMP L2 ; join common code to disable video access
-
-
- ; WANG_KEY is the Wang-PC version of the BIOS_KEY routine.
-
- WANG_KEY:
- PUSH BX ; preserve register across call
- L1: ; loop here to wait for a key to become ready
- MOV AL,15 ; Wang BIOS function code for GET KEY STATUS
- MOV BL,2 ; another parameter for Wang BIOS - I'm not sure which
- INT 088 ; call Wang BIOS to get the status and maybe the key
- TEST AL ; do we have a key?
- JNZ L1 ; loop if not, to try again
- XCHG AX,BX ; we do: swap the key code into AL for return
- POP BX ; restore clobbered register
- RET
-
-
- ; WANG_BELL is the Wang-PC version of the BIOS_BELL routine.
-
- WANG_BELL:
- MOV BX,7 ; BL=7 is the BELL code; the BIOS also wants BH=0
- MOV AL,6 ; Wang BIOS function code for CONSOLE OUTPUT
- INT 088 ; output the BELL control code to the Wang console
- RET
-
-
- ;------------------
- ; TI-PC INTERFACE
- ;------------------
-
- ; Thanks to David R. Cook for writing the following code. I have reformatted
- ; it to look like the rest of my code, and made optimizations.
-
- TIPC_KEYS:
- DB 0B5 ; key code for F11 - the help key
- DB 0AA-FUNC ; F1 is code 0AB on the TI-PC
- L1:
- DB 0C0 ; down-arrow key
- DB 0C1 ; no PgDn key on the TI-PC, so we use alt-down-arrow code
- DB 0B8 ; up-arrow key
- DB 0B9 ; no PgUp key on the TI-PC, so we use alt-up-arrow code
- DB 0B7 ; HOME key
- DB 0CA ; shift-F7 key
- DB 0E0 ; alt-F9 key
- N_CONTROL_KEYS equ $-L1
-
- DW F11_HELP ; pointer to help message
-
- L2:
- DW TIPC_COPY ; VID_COPY routine
- DW TIPC_ATTR ; VID_ATTR routine
- DW TIPC_FIX ; VID_FIX routine
- DW TIPC_BELL ; BIOS_BELL routine
- DW TIPC_KEY ; BIOS_KEY routine
- DW RET
- DW RET
- DW 0DE00 ; new value for VIDEO_SEG
- DB 0F ; normal-video attribute for the TI-PC
- DB 01F ; reverse-video attribute for the TI-PC
- N_BIOS_CALLS equ ($-L2)/2
-
- ; Other TI keycodes:
-
- ; key +shift +alt +ctrl plain
- ; ----------------------------------
- ; F1 0C4 0D8 0CE 0AB
- ; ...
- ; F10 0CD 0E1 0D7 0B4
- ; F11 "x" "|" "z" 0B5
- ; F12 "y" "}" "{" 0B6
- ;
- ; PRNT 0E2
- ; INS 098 09A 099 0C2
- ; DEL 0A8 0AA 0A9 0C3
- ; UP AR 0F8 0B9 0F4
- ; DN AR 0F9 0C1 0E6
- ; LT AR 0FB 0BC 0E3 0BB
- ; RT AR 0FA 0BE 0E4 0BD
- ; HOME 0F6 0F5 0E7
- ; TAB 07F ignored ignored 09
-
-
-
- ; TIPC_CONFIG is the BIOS initialization routine for the TI-PC. We copy the
- ; values in TIPC_KEYS to various locations, then we drop into TIPC_FIX,
- ; to reset the cursor.
-
- TIPC_CONFIG:
- MOV SI,TIPC_KEYS ; point to configuration-table for TI-PC's BIOS
- CALL NEW_KEYS ; copy the values to our tables
- TIPC_FIX:
- MOV AH,014 ; BIOS function code for "clear graphics screen"
- INT 049 ; clear the graphics screen
- MOV AH,013 ; BIOS function code for "clear text screen"
- INT 049 ; clear the text screen
- MOV AH,2 ; BIOS function code for "position the cursor"
- MOV DX,1 BY 24 ; first column, 24th row
- INT 049 ; move the user's cursor to the bottom left corner
- RET
-
-
- ; TIPC_COPY is the VID_COPY routine for the TIPC video board. The attribute
- ; AH is written to a single memory-mapped latch in the video segment.
- ; Then the text bytes can be copied as-is.
-
- TIPC_COPY:
- ES MOV B[01801],AH ; set the attribute latch
- SHR DI,1 ; adjust the video address for bytes, not words
- REP MOVSB ; copy the text as-is
- SHL DI,1 ; restore the video address to words, not bytes
- RET
-
-
- ; TIPC_ATTR is the VID_ATTR routine for TI-PC computer. We change the
- ; attribute latch to the one provided in AL, then we add 0 to the video
- ; character in memory, causing the new latch value to take effect.
-
- TIPC_ATTR:
- SHR DI,1 ; adjust video address for bytes, not words
- ES MOV AH,B[DI] ; fetch the character
- ES MOV B[01801],AL ; rewrite the latch with the caller's value
- ES MOV B[DI],AH ; re-write the value already there, to effect the latch
- SHL DI,1 ; restore DI
- RET
-
-
- ; TIPC_KEY is the BIOS_KEY routine for TI_PC computer. We must transform the
- ; two-byte code returned by the TIPC BIOS into the single code AL expected by
- ; the rest of the debugger. The only differences to IBM_KEY are the interrupt
- ; number, and the mapping of the codes received and returned.
-
- TIPC_KEY:
- MOV AH,0 ; function code for GET KEY
- INT 04A ; get the keystroke from the TIPC BIOS
- TEST AL ; is the return AL nonzero?
- JNZ RET ; if yes then AL is our return code
- MOV AL,AH ; AL is zero, so AH determines the return code
- ADD AL,080-16 ; shift the values into a range not seen directly in AL
- RET
-
-
- ; TIPC_BELL is the BIOS_BELL routine for TIPC-PC computer. We output the code
- ; 07 to the BIOS's console output routine. The only difference to IBM_KEY is
- ; the interrupt number.
-
- TIPC_BELL:
- MOV AX,0E07 ; AH= console out function number; AL="BELL" control code
- INT 049 ; output BELL to the console
- RET
-
-
- ;------------------
- ; SANYO INTERFACE
- ;------------------
-
- ; Thanks to Jerry Farnsworth for providing the information necessary for me
- ; to program this interface.
-
- SANYO_KEYS:
- DB 0DC ; key code for Ctrl-PF5 -- the help key
- DB 0 ; same function codes as IBM-PC
- L1:
- DB 0C0 ; down-arrow key
- DB 0C1 ; PgDn key
- DB 0B8 ; up-arrow key
- DB 0B9 ; PgUp key
- DB 0B7 ; HOME key
- DB 0CA ; shift-F7 key is Ctrl 7 on the Sanyo
- DB ALT_F 9 ; Ctrl-Shift-PF4 will restore a trashed screen
- N_CONTROL_KEYS equ $-L1
-
- DW PF5_HELP ; pointer to help message
-
- L2:
- DW SANYO_COPY ; VID_COPY routine
- DW SANYO_ATTR ; VID_ATTR routine
- DW SANYO_FIX ; VID_FIX routine
- DW IBM_BELL ; BIOS_BELL routine
- DW IBM_KEY ; BIOS_KEY routine
- DW SANYO_SAVE ; we must save the BIOS cursor position
- DW SANYO_RESTORE ; we must restore the BIOS cursor position
- DW 07C00 ; new value for VIDEO_SEG
- DB 07 ; normal-video attribute for the Sanyo-PC
- DB 0F0 ; reverse-video attribute for the Sanyo-PC
- N_BIOS_CALLS equ ($-L2)/2
-
-
- ; Other Sanyo keycodes:
-
- ; IBM Sanyo IBM Sanyo
-
- ; Alt Ctrl Shift DOWN numeric pad 5
- ; Alt Fn Ctrl Fn END numeric pad 2
- ; Shift Fn Ctrl n
- ; Ctrl 2 Ctrl ` Ctrl F12345 Ctrl ={}:"
- ; Ctrl 6 Ctrl tilde Ctrl F678910 Ctrl ;',./
-
-
-
- ; SANYO_CONFIG is the BIOS initialization routine for a Sanyo 55x. We copy the
- ; values of SANYO_KEYS to various locations, fetch and store the current
- ; video page, and set the user cursor to the lower left of the screen.
-
- ; SANYO_FIX insures a screen refresh by filling the "actual" buffers of SCREEN_P
- ; with impossible FF-values.
-
- SANYO_CONFIG:
- MOV SI,SANYO_KEYS ; point to configuration-table for SANYO's BIOS
- CALL NEW_KEYS ; copy the values to our tables
- MOV AH,15 ; function number for fetching the video page
- INT 010 ; set BH to the current video page
- CS MOV SANYO_PAGE,BH ; store the page throughout the debugging session
- MOV DX,24 BY 0 ; load coordinates for the lower left corner
- CALL SET_SANYO_POS ; store this position
- CALL SANYO_RESTORE ; this call causes the user cursor to move there
- SANYO_FIX:
- NO_ACTUAL:
- MOV AX,0FFFF ; load AH and AL with the 0FF impossible-value
- FILL_ACTUAL:
- MOV ES,SS ; destination segment is our stack, for buffer-fill
- MOV DI,SCREEN_P+80 ; point to the actual-buffer for the first line
- MOV DL,24 ; load the count of actual lines to fill
- L2:
- MOV CX,40 ; number of words in the actual buffer
- REP STOSW ; fill the buffer with the words
- ADD DI,256-80 ; advance output pointer to the next line's actual buff.
- DEC DL ; count down lines
- JNZ L2 ; loop to fill the next line
- RET
-
-
- ; SANYO_COPY is the VID_COPY routine for the Sanyo. The Sanyo does not have
- ; a hardware character generator, so we call the BIOS to copy bit-patterns
- ; to the screen.
-
- SANYO_COPY:
- MOV AX,DI ; fetch the output character number
- ADD DI,CX ; add the character count
- ADD DI,CX ; add it twice, to advance by words not bytes
- PUSH BX,DI ; preserve caller's BX and return DI value
- MOV BH,0 ; load the page number
- SANYO_PAGE EQU B[$-1] ; previous immediate value is plugged in
- CALL GET_ROWCOL ; convert character number AX into row-and-column DX
- DEC DX ; cancel the following first INC DX
- L1: ; loop here for every character already out there
- INC DX ; advance the column number DL to the next position
- LODSB ; fetch the next character
- MOV BL,AL ; save the character in BL
- XCHG AL,[SI+79] ; swap it with the already-out-there value
- CMP AL,BL ; is the character already out there?
- LOOPE L1 ; loop if it is
- JE >L2 ; jump if the characters are exhausted
- INC CX ; undo the previous LOOPE's decrement of CX
- CALL SET_IBM_CURSOR ; move the cursor to the indicated position
- MOV AL,BL ; fetch the character to be output
- MOV BL,7 ; load the attribute code, always 7 in Sanyo's case
- PUSH CX ; save the character count
- MOV CX,1 ; we are outputting 1 character in this call
- MOV AH,9 ; BIOS function number for WRITE_CHAR
- INT 010 ; write the character to the screen
- POP CX ; restore the character count
- LOOP L1 ; loop to check for another output character
- L2:
- POP DI,BX ; restore clobbered registers
- RET
-
-
- ; SANYO_ATTR is the VID_ATTR routine for the Sanyo. We use the BIOS to
- ; move the cursor to the current position, read the character that is
- ; already there, and rewrite the character with the new attribute.
-
- SANYO_ATTR:
- PUSH BX,CX,DX,DI ; save registers across call
- PUSH AX ; save the attribute across the repositioning
- MOV AX,DI ; fetch the character number
- CALL GET_ROWCOL ; convert the character number AX to row-and-column DX
- CS MOV BH,SANYO_PAGE ; load the current page number
- CALL SET_IBM_CURSOR ; move the cursor to the required location
- MOV AH,8 ; function number for READ_CHARACTER
- INT 010 ; set AL to the character already there
- POP DX ; restore DL = new attribute byte
- MOV BL,DL ; copy the attribute to BL where the BIOS expects it
- MOV CX,1 ; we are writing one character only
- MOV AH,9 ; BIOS function number for WRITE_CHAR
- INT 010 ; write the character to the screen
- POP DI,DX,CX,BX ; restore clobbered registers
- RET
-
-
- ; GET_ROWCOL an address AX into a row number DH and column number DL. The input
- ; AX address is twice the number of characters from the start of the screen
- ; to the current cursor position.
-
- GET_ROWCOL:
- MOV DI,160 ; each line advances the address by 160
- SUB DX,DX ; the upper word of the dividend DXAX is always 0
- DIV DI ; convert the address to row AX, column DL*2
- MOV DH,AL ; the row is returned in DH
- SHR DL,1 ; the column is returned in DL
- RET
-
-
- ; SANYO_SAVE is the BIOS_SAVE routine for the Sanyo. We record the user's
- ; cursor position, so that it can be restored by BIOS_RESTORE.
-
- SANYO_SAVE:
- MOV AH,3 ; BIOS function number for READ_CURSOR_POSITION
- INT 010 ; set DX to the current user cursor position
- SET_SANYO_POS:
- CS MOV SANYO_POS,DX ; store the cursor position DX
- RET
-
-
- ; SANYO_RESTORE is the BIOS_RESTORE routine for the Sanyo. We set the
- ; user's sursor position to the place previously stored.
-
- SANYO_RESTORE:
- MOV DX,0 ; fetch the cursor position
- SANYO_POS EQU W[$-2] ; the above immedaite operand has been plugged
- JMP SET_IBM_CURSOR ; jump to set the user's cursor
-
-
- ;------------------------
- ; TANDY 2000 INTERFACE
- ;------------------------
-
- ; Thanks to John B. Harrell, Contributing Editor PC Resuorce, for writing
- ; the following code. I have made minor code optimizations.
-
- TANDY_KEYS:
- DB ALT_F 10 ; code for Alt-F10 -- the HELP key
- DB 0 ; F1 code same as on IBM-PC
- L1:
- DB 0C0 ; Down Arrow
- DB 0C1 ; PgDn
- DB 0B8 ; Up Arrow
- DB 0B9 ; PgUp
- DB 0B7 ; Home
- DB 0CA ; Shift F7
- DB ALT_F 9 ; Alt-F9 fixes a trashed screen
- N_CONTROL_KEYS EQU $-L1
-
- DW ALTF10_HELP ; pointer to help message
-
- L2:
- DW MONO_COPY ; VID_COPY routine
- DW IBM_ATTR ; VID_ATTR routine
- DW TANDY_FIX ; VID_FIX routine
- DW IBM_BELL ; BIOS_BELL routine
- DW IBM_KEY ; BIOS_KEY routine
- DW RET ; BIOS_SAVE routine needed for Sanyo only
- DW RET ; BIOS_RESTORE routine needed for Sanyo only
- TANDY_VSEG DW ? ; Tandy 2000 floating video segment address = VIDEO_SEG
- DB 0A ; normal video attribute on Tandy 2000
- DB 0CA ; reverse video attribute on Tandy 2000
- N_BIOS_CALLS EQU ($-L2)/2
-
- ; Other Tandy 2000 keycodes:
-
- ; key +shift +alt +ctrl plain
- ; ----------------------------------
- ; F1 0C4 0D8 0CE 0AB
- ; ...
- ; F10 0CD 0E1 0D7 0B4
- ; F11 012 "&" 01C 008
- ; F12 013 "`" 01D 009
- ;
- ; PRNT --- 0B6 0E2 010
- ; INS 0F9 010 00F 0C2
- ; DEL 0FA 00E 00D 0C3
- ; UP AR 0F5 001 000
- ; DN AR 0F6 007 006
- ; LT AR 0F7 002 0E3 0BB
- ; RT AR 0F8 --- 0E4 0BD
- ; HOME 0BA 016 0E7
- ; TAB 07F 0FE 0FD 009
- ; BKSP 008 0FC 07F 008
- ; TAB 07F 0FE 0FD 009
- ; ESC 01B 0FB 01B 01B
- ; END --- --- 0E5 0BF
- ; PGUP --- --- 0F4 0B9
- ; PGDN --- --- 0E6
-
- TANDY_CONFIG:
- INT 012 ; get reported memory size in KBytes
- MOV CL,6 ; shift count = * 64 for Kbytes to paragraphs
- SHL AX,CL ; convert to paragraphs
- ADD AX,0080 ; point to starting location of monochrome video buffer
- CS MOV TANDY_VSEG,AX ; save in data structure
- MOV SI,TANDY_KEYS ; point to configuration table for Tandy 2000
- CALL NEW_KEYS ; copy the value into BIOS tables
- TANDY_FIX:
- MOV AX,0 BY 2 ; AH= BIOS function code for SET_VIDEO_MODE; AL = mode 0
- INT 16 ; force a monochrome video mode
- JMP SET_IBM_LOW_LEFT ; move the cursor to the lower left corner
-